package com.example.demo.module.repository.service.impl;

import com.baomidou.mybatisplus.core.metadata.OrderItem;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.example.demo.common.entity.response.ResCode;
import com.example.demo.common.exception.CommonException;
import com.example.demo.common.service.impl.BaseServiceImpl;
import com.example.demo.entity.pojo.repository.MaterialPoJo;
import com.example.demo.entity.pojo.repository.RepositoryPoJo;
import com.example.demo.module.repository.mapper.MaterialMapper;
import com.example.demo.module.repository.service.MaterialService;
import com.example.demo.module.repository.service.RepositoryService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.util.List;
import java.util.Objects;

/**
 * .
 *
 * @author Mei Ruoxiao
 * @since 2020/9/15
 */
@Service
@Slf4j
public class MaterialServiceImpl extends BaseServiceImpl<MaterialMapper, MaterialPoJo> implements MaterialService {
    @Resource
    private RepositoryService repositoryService;

    @Override
    public long create(MaterialPoJo poJo, long companyId) {
        log.info("create:[poJo:{}, companyId:{}]", poJo, companyId);
        poJo.setCompanyId(companyId);
        return create(poJo).getId();
    }

    @Override
    public MaterialPoJo getOne(String code) {
        log.info("getOne:[code:{}]", code);
        return getOne(Wrappers.<MaterialPoJo>lambdaQuery()
                .eq(MaterialPoJo::getCode, code)
        );
    }

    @Override
    public MaterialPoJo get(String verify) {
        log.info("get:[verify:{}]", verify);
        return getOne(Wrappers.<MaterialPoJo>lambdaQuery()
                .eq(MaterialPoJo::getVerify, verify)
        );
    }

    @Override
    public Page<MaterialPoJo> page(String keywords, int type, Long repositoryId, int page, int size, long companyId) {
        log.info("page:[keywords:{}, type:{}, page:{}, size:{}, companyId:{}]", keywords, type, page, size, companyId);
        return this.page(Wrappers.<MaterialPoJo>lambdaQuery()
                        .eq(MaterialPoJo::getCompanyId, companyId)
                        .eq(MaterialPoJo::getType, type)
                        .like(Objects.nonNull(keywords), MaterialPoJo::getName, keywords)
                        .or()
                        .like(Objects.nonNull(repositoryId), MaterialPoJo::getRepositoryId, repositoryId),
                page,
                size,
                OrderItem.desc("create_time")
        );
    }

    @Override
    public List<MaterialPoJo> listByRepositoryId(long repositoryId, long companyId) {
        log.info("listByRepositoryId:[repositoryId:{}, companyId:{}]", repositoryId, companyId);
        return list(Wrappers.<MaterialPoJo>lambdaQuery()
                .eq(MaterialPoJo::getRepositoryId, repositoryId)
                .eq(MaterialPoJo::getCompanyId, companyId));
    }

    @Override
    public boolean move(List<Long> ids, long repositoryId, int quantity, int type, long companyId) {
        log.info("move:[ids:{}, repositoryId:{}, type:{}, companyId:{}]", ids, repositoryId, type, companyId);
        List<MaterialPoJo> list = list(Wrappers.<MaterialPoJo>lambdaQuery()
                .in(Objects.nonNull(ids), MaterialPoJo::getId, ids)
                .eq(MaterialPoJo::getType, type)
                .eq(MaterialPoJo::getCompanyId, companyId)
        );
        //判断该仓库文件夹是否存在
        RepositoryPoJo repositoryPoJo = repositoryService.getOne(Wrappers.<RepositoryPoJo>lambdaQuery()
                .eq(RepositoryPoJo::getType, type)
                .eq(RepositoryPoJo::getId, repositoryId)
                .eq(RepositoryPoJo::getCompanyId, companyId)
        );
        log.info("move:[repositoryPoJo:{}]", repositoryPoJo);
        if (Objects.nonNull(repositoryPoJo) && Objects.nonNull(list)) {
            log.info("move:[start]");
            list.forEach(materialPoJo -> {
                materialPoJo.setRepositoryId(repositoryId);
                if (materialPoJo.getStock() < quantity) {
                    throw CommonException.of(materialPoJo.getName(), ResCode.REPOSITORY_NOT_ENOUGH_STOCK);
                } else {
                    int remainStock = materialPoJo.getStock() - quantity;
                    materialPoJo.setStock(remainStock);
                    materialPoJo.setGarbage(materialPoJo.getGarbage() + quantity);
                }
            });
            this.updateBatchById(list);
            log.info("move:end[ids:{}]", ids);
            return !CollectionUtils.isEmpty(ids);
        }
        return false;
    }
}
